﻿/*
 * Last review by   : Yaser
 * Last review date : JUL-25-09 
 */
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using ERP.Framework.Components.SerializationHelper.Interfaces;
using ERP.Framework.Components.Utilities.TracingHelper;

namespace ERP.Framework.Components.SerializationHelper
{
    /// <summary>
    /// XML serializing
    /// </summary>
    public abstract class XmlSerializingManager : ISerializingManager
    {
        #region Members

        private const string TRACING_CATEGORY = "ERP.Framework.Components.SerializationHelper.XmlSerializingManager";
        private const string TO_BE_REMOVED_KEY = "ToBeRemovedStrings";

        #endregion

        #region Methods

        /// <summary>
        /// Prepare serialization string
        /// </summary>
        /// <param name="serializedString">The serialized string.</param>
        /// <returns></returns>
        private static string TrimSerializedString(string serializedString)
        {
            string m_toReplaceArray = new System.Resources.ResourceManager(typeof(XmlSerializingManager)).GetString(TO_BE_REMOVED_KEY),
                m_result = serializedString;

            foreach (string item in m_toReplaceArray.Split('#'))
            {
                m_result = m_result.Replace("<" + item + ">", "");
            }

            //set boolean values
            m_result = m_result.Replace("False", "false").Replace("True", "true");
            return m_result;
        }

        /// <summary>
        /// Serialize object
        /// </summary>
        /// <param name="obj">object to serialize</param>
        /// <returns>serialized object as string</returns>
        public static string SerializeObject(object obj)
        {
            TraceUtil.Write(TRACING_CATEGORY, "SerializeObject : Start");
            try
            {
                String XmlizedString = null;
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(obj.GetType());
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
                xs.Serialize(xmlTextWriter, obj);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                UTF8Encoding z = new UTF8Encoding();
                XmlizedString = z.GetString(memoryStream.ToArray());
                XmlizedString = TrimSerializedString(XmlizedString);
                TraceUtil.Write(TRACING_CATEGORY, "SerializeObject : End");
                return XmlizedString;
            }
            catch (Exception e)
            {
                ERP.Framework.Components.ExceptionHandler.ExceptionPublisher.PublishException(e);
                TraceUtil.Write(TRACING_CATEGORY, "SerializeObject : End");
                return null;
            }
        }

        /// <summary>
        /// Deserialize string to object
        /// </summary>
        /// <typeparam name="T">object type</typeparam>
        /// <param name="serializedText">serialization string</param>
        /// <returns>object</returns>
        public static object DeserializeObject<T>(string serializedText)
        {
            TraceUtil.Write(TRACING_CATEGORY, "DeserializeObject : Start");
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));
                UTF8Encoding z = new UTF8Encoding();
                MemoryStream memoryStream = new MemoryStream(z.GetBytes(TrimSerializedString(serializedText)));
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
                TraceUtil.Write(TRACING_CATEGORY, "DeserializeObject : End");
                return xs.Deserialize(memoryStream);
            }
            catch (Exception e)
            {
                ERP.Framework.Components.ExceptionHandler.ExceptionPublisher.PublishException(e);
                TraceUtil.Write(TRACING_CATEGORY, "DeserializeObject : End");
                return null;
            }
        }

        /// <summary>
        /// Serialize object
        /// </summary>
        /// <param name="obj">object to serialize</param>
        /// <returns>serialized object as string</returns>
        string ISerializingManager.SerializeObject(object obj)
        {
            return SerializeObject(obj);
        }

        /// <summary>
        /// Deserialize string to object
        /// </summary>
        /// <typeparam name="T">object type</typeparam>
        /// <param name="serializedText">serialization string</param>
        /// <returns>object</returns>
        object ISerializingManager.DeserializeObject<T>(string serializedText)
        {
            return DeserializeObject<T>(serializedText);
        }

        #endregion
    }
}
